package com.gugu.procedure.service;


import cn.hutool.core.map.MapUtil;
import com.gugu.procedure.bean.*;
import com.gugu.procedure.common.Constant;
import com.gugu.procedure.dao.*;
import com.gugu.procedure.util.JsonUtil;
import com.gugu.procedure.vo.OrderProductionRecordVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class OrderProductionRecordService {

    @Autowired
    private OrderProductionRecordDao orderProductionRecordDao;
    @Autowired
    private InsideOrderService insideOrderService;
    @Autowired
    private ProductionRecordDao productionRecordDao;
    @Autowired
    private ProductionDao productionDao;
    @Autowired
    private OrderItemDao orderItemDao;
    @Autowired
    private ReplenishmentDao replenishmentDao;

    public List <OrderProductionRecordVo> queryOrderProductionRecord2(String orderNo) {
        List <OrderProductionRecordVo> voList = new ArrayList <>();
        //先查询订单有哪些工艺
        Production production = productionDao.findOrderProcedures(orderNo);
        if (Objects.isNull(production)) {
            return new ArrayList <>();
        }

        List <String> list2 = productionDao.findProcedures(orderNo);
        List <String> list = new ArrayList <>(); //存储了整个订单设计的工艺流程
        for (String s : list2) {
            List <String> list3 = JsonUtil.decodeJsonToList(s, String.class);
            for (String ss : list3) {
                if (!list.contains(ss)) {
                    list.add(ss);
                }
            }
        }
        //  然后需要排序 激光-整形-扩大-成形-一设-斜线一研-设定-二研-品管
        // 激光 - 整形 - 扩大 - 成形 - 一设 - 过粉 - 斜线-一研 - 设定 - 二研 - 品管（镜检 - 挪检 - 车制 - 打码 - 包装）
        List <String> list4 = new ArrayList <>();
        list4.add(Constant.PROCEDURE_LASER);
        list4.add(Constant.PROCEDURE_PLASTIC);
        list4.add(Constant.PROCEDURE_EXPANSION);
        list4.add(Constant.PROCEDURE_FORMING);
        list4.add(Constant.PROCEDURE_SET1);
        list4.add(Constant.PROCEDURE_GF1);
        list4.add(Constant.PROCEDURE_GF2);
        list4.add(Constant.PROCEDURE_SLASH);
        list4.add(Constant.PROCEDURE_RESEARCH1);
        list4.add(Constant.PROCEDURE_SETING);
        list4.add(Constant.PROCEDURE_RESEARCH2);
        list4.add(Constant.PROCEDURE_QC_JJ);
        list4.add(Constant.PROCEDURE_QC_LJ);
        list4.add(Constant.PROCEDURE_QC_CZ);
        list4.add(Constant.PROCEDURE_QC_DM);
        list4.add(Constant.PROCEDURE_QC_BZ);
        List <String> sortList = new ArrayList <>();
        for (String s : list4) {
            if (list.contains(s)) {
                sortList.add(s);
            }
        }
        InsideOrder insideOrder = insideOrderService.queryInsideOrderByOrderNo(orderNo);
        // 查询该订单的每个工艺对应的情况
        for (int i = 0; i < sortList.size(); i++) {
            String procedure = sortList.get(i);
            OrderProductionRecordVo vo = new OrderProductionRecordVo();
            Map <String, Object> map = productionDao.queryForUpdate(orderNo, procedure, "%" + procedure + "%");
            Integer total = MapUtil.getInt(map, "total");
            Integer hasDone = MapUtil.getInt(map, "hasDone");
            Integer ngNum = MapUtil.getInt(map, "ngNum");
            Integer toBeCompleted = total - hasDone - ngNum;
            if ("U".equals(insideOrder.getType())) {
                vo.setNgNumStr(ngNum + "");
            }
            // 查询新品订单的补料申请数量
            else {
                int replenishmentCount = replenishmentDao.queryReplenishmentCount(orderNo, null, procedure);
                vo.setReplenishmentCount(replenishmentCount);
                vo.setNgNumStr(replenishmentCount + "");
            }
            vo.setTotal(total);
            vo.setNgNum(ngNum);
            vo.setHasDone(hasDone);
            vo.setToBeCompleted(toBeCompleted);
            vo.setSeque(i + 1);
            vo.setOrderNo(orderNo);
            vo.setProduction(procedure);
            OrderProductionRecord orderProductionRecord = orderProductionRecordDao.findTopByOrderNoAndProductionAndStatus(orderNo, procedure, Constant.STATUS_1);
            if (Objects.isNull(orderProductionRecord)) {
                vo.setStatus("0");
            } else {
                vo.setStartTime(orderProductionRecord.getStartTime());
                vo.setEndTime(orderProductionRecord.getEndTime());
                if (Objects.nonNull(orderProductionRecord.getStartTime()) && Objects.nonNull(orderProductionRecord.getEndTime())) {
                    vo.setStatus("2");
                } else {
                    vo.setStatus("1");
                }
            }
            voList.add(vo);
        }
        return voList;
    }


    public List <OrderProductionRecordVo> queryOrderProductionRecord(String orderNo) {
        List <OrderProductionRecordVo> voList = new ArrayList <>();
        //先查询订单有哪些工艺
        Production production = productionDao.findOrderProcedures(orderNo);
        if (Objects.isNull(production)) {
            return new ArrayList <>();
        }

        List <String> list2 = productionDao.findProcedures(orderNo);
        List <String> list = new ArrayList <>(); //存储了整个订单设计的工艺流程
        for (String s : list2) {
            List <String> list3 = JsonUtil.decodeJsonToList(s, String.class);
            for (String ss : list3) {
                if (!list.contains(ss)) {
                    list.add(ss);
                }
            }
        }
        //  然后需要排序 激光-整形-扩大-成形-一设-斜线一研-设定-二研-品管
        // 激光 - 整形 - 扩大 - 成形 - 一设 - 过粉 - 斜线-一研 - 设定 - 二研 - 品管（镜检 - 挪检 - 车制 - 打码 - 包装）
        List <String> list4 = new ArrayList <>();
        list4.add(Constant.PROCEDURE_LASER);
        list4.add(Constant.PROCEDURE_PLASTIC);
        list4.add(Constant.PROCEDURE_EXPANSION);
        list4.add(Constant.PROCEDURE_FORMING);
        list4.add(Constant.PROCEDURE_SET1);
        list4.add(Constant.PROCEDURE_GF1);
        list4.add(Constant.PROCEDURE_GF2);
        list4.add(Constant.PROCEDURE_SLASH);
        list4.add(Constant.PROCEDURE_RESEARCH1);
        list4.add(Constant.PROCEDURE_SETING);
        list4.add(Constant.PROCEDURE_RESEARCH2);
        list4.add(Constant.PROCEDURE_QC_JJ);
        list4.add(Constant.PROCEDURE_QC_LJ);
        list4.add(Constant.PROCEDURE_QC_CZ);
        list4.add(Constant.PROCEDURE_QC_DM);
        list4.add(Constant.PROCEDURE_QC_BZ);
        List <String> sortList = new ArrayList <>();
        for (String s : list4) {
            if (list.contains(s)) {
                sortList.add(s);
            }
        }
        InsideOrder insideOrder = insideOrderService.queryInsideOrderByOrderNo(orderNo);
        // 用于计算total
        List <OrderItem> orderItems = orderItemDao.findByOrderNo(orderNo);
        List <Production> productions = productionDao.listByOrderNo(orderNo);

        List <ProductionRecord> productionRecords = productionRecordDao.findByOrderNo(orderNo);

        List <OrderProductionRecord> orderProductionRecords = orderProductionRecordDao.findAllByOrderNoAndStatus(orderNo, Constant.STATUS_1);

        // 查询该订单的每个工艺对应的情况
        for (int i = 0; i < sortList.size(); i++) {
            String procedure = sortList.get(i);
            OrderProductionRecordVo vo = new OrderProductionRecordVo();
            List <String> specss = filterSpecs(productions, procedure);
            //  Map <String, Object> map = productionDao.queryForUpdate(orderNo, procedure, "%" + procedure + "%");
            Integer total = total(orderItems, specss);
            Integer hasDone = hasDone(productionRecords, procedure);
            Integer ngNum = ngNum(productionRecords, procedure);
            Integer toBeCompleted = total - hasDone - ngNum;
            if ("U".equals(insideOrder.getType())) {
                vo.setNgNumStr(ngNum + "");
            }
            // 查询新品订单的补料申请数量
            else {
//                int replenishmentCount = replenishmentDao.queryReplenishmentCount(orderNo, null, procedure);
//                vo.setReplenishmentCount(replenishmentCount);
//                vo.setNgNumStr(replenishmentCount + "");
            }
            vo.setTotal(total);
            vo.setNgNum(ngNum);
            vo.setHasDone(hasDone);
            vo.setToBeCompleted(toBeCompleted);
            vo.setSeque(i + 1);
            vo.setOrderNo(orderNo);
            vo.setProduction(procedure);
            OrderProductionRecord orderProductionRecord = filterOrderProductionRecord(orderProductionRecords, procedure);
            if (Objects.isNull(orderProductionRecord)) {
                vo.setStatus("0");
            } else {
                vo.setStartTime(orderProductionRecord.getStartTime());
                vo.setEndTime(orderProductionRecord.getEndTime());
                if (Objects.nonNull(orderProductionRecord.getStartTime()) && Objects.nonNull(orderProductionRecord.getEndTime())) {
                    vo.setStatus("2");
                } else {
                    vo.setStatus("1");
                }
            }
            voList.add(vo);
        }
        return voList;
    }


    private List <String> filterSpecs(List <Production> productions, String production) {
        List <Production> list = productions.
                stream().filter(bean -> bean.getProcedures().contains(production)).collect(Collectors.toList());
        return list.stream().map(bean -> bean.getSpecs()).collect(Collectors.toList());
    }

    private Integer total(List <OrderItem> orderItems, List <String> specss) {
        List <OrderItem> list = orderItems.stream().filter(bean -> specss.contains(bean.getSpecs())).collect(Collectors.toList());
        Integer total = 0;
        for (OrderItem orderItem : list) {
            total = total + Integer.parseInt(orderItem.getAmount());
        }
        return total;
    }


    private OrderProductionRecord filterOrderProductionRecord(List <OrderProductionRecord> orderProductionRecords, String production) {
        List <OrderProductionRecord> list = orderProductionRecords.stream().filter(bean -> bean.getProduction().equals(production)).collect(Collectors.toList());
        if (list.size() == 0) {
            return null;
        }
        return list.get(0);
    }

    private Integer hasDone(List <ProductionRecord> productionRecords, String production) {
        List <ProductionRecord> list = productionRecords.
                stream().filter(bean -> bean.getStatus().equals("1") && bean.getNgTag().equals("0")
                && bean.getEndTime() != null && bean.getProduction().equals(production)).collect(Collectors.toList());
        return list.size();
    }

    private Integer ngNum(List <ProductionRecord> productionRecords, String production) {
        List <ProductionRecord> list = productionRecords.
                stream().filter(bean -> bean.getStatus().equals("1") && bean.getNgTag().equals("1")
                && bean.getEndTime() != null && bean.getProduction().equals(production)).collect(Collectors.toList());
        return list.size();
    }
}
